/*
 * UartDrv.c
 *
 *  Created on: Apr 6, 2015
 *      Author: ma.xw
 */
#include "UartDrv.h"
#include <S3C2440addr.h>
#include <commlib.h>
#include <eventQueue.h>

#define GPH2_3_MASK (0xF0)
#define MAX_SEND_LEN (256)

typedef enum {
    UART_IDLE,
    UART_BUSY,
} UART_ST;
typedef struct {
    UART_ST st;
    unsigned short len;
    unsigned short send_idx;
    unsigned char data[MAX_SEND_LEN];
} Send_Control;
Send_Control send_control;

void uart_init(unsigned int baud_rate) {
    send_control.st = UART_IDLE;
    send_control.len = 0;
    send_control.send_idx = 0;

    //config GPF2 -> TXD0, GPF3 -> RXD0
    rGPHCON &= ~GPH2_3_MASK;
    rGPHCON |= 0xA0;

    rGPHUP = 0x00;//enable pull up

    rULCON0 = 0x3; //uart line control register,8 bit Character, 1 stop bit, no parity

    rUCON0 = 0x5;//PCLK(50MHz) as clock, send/receive by query or interupt

    rUFCON0  = 0x00;     // 不使用FIFO
    rUMCON0  = 0x00;     // 不使用流控


    //UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
    //(unsigned short)(50000000 / (baud_rate * 16)) - 1;//baud=115200 -> 26.12->26=0x1A
    rUBRDIV0 = 26;

    rINTMSK &= ~(1 << 28); //clear mask bit of INT_UART0
    rINTSUBMSK &= ~(3 << 0); //clear INTSUBMSK.bit[1:0] to enable INT_RXD0 and INT_TXD0
}



void enable_send() {
}

void enable_recv() {
}

#define IS_SENDING (0 == (rUTRSTAT0 & (1 << 1)))
int uart_print_char(unsigned char c) {
    while (IS_SENDING) {}
    rUTXH0 = c;
    return 0;
}

int uart_print(const char* pbuf) {
    while(UART_BUSY == send_control.st){}

    send_control.len = my_strlen(pbuf); //not inlcude '\0', example strlen("a") = 1
    send_control.send_idx = 0;
    //my_memset(send_control.data, 0, sizeof(send_control.data));
    if (send_control.len > MAX_SEND_LEN) {
        send_control.len = MAX_SEND_LEN;
    }
    my_memcpy(send_control.data, pbuf, send_control.len);

    if(send_control.len != send_control.send_idx) {
        send_control.st = UART_BUSY;
        ++send_control.send_idx;
        uart_print_char(send_control.data[0]);
    }
    return 0;
}

//int uart_printf(char*, ...) {
//    return 0;
//}

void uart_on_recv_intr(unsigned char c) {
    //err check
    // to read rUERSTAT0 = 0;

    Queue_Element e;
    e.cmd = CMD_UART_RECEVEI_DONE;
    e.data[0] = c;
    push_event(&g_Main_Queue, &e);
}

void uart_on_send_done_intr() {
    if(send_control.len != send_control.send_idx) {
        uart_print_char(send_control.data[send_control.send_idx]);
        ++send_control.send_idx;
    } else {//send string done
        send_control.st = UART_IDLE;
        send_control.len = 0;
        send_control.send_idx = 0;
    }
}


